#include "bsp_gpio.h"

void gpio_init(GPIO_Type *gpio , int IO_num , gpio_pin_config_t *config ){
    if(config->direction == gpio_output){
        gpio->GDIR |= (1<<IO_num);
        gpio_write_pin(gpio , IO_num , config->output);
    }
    else{
        gpio->GDIR &= ~(1<<IO_num);
    }
    if(config->interruputMode != 0){
        gpio_interruput_init(gpio , IO_num , config->interruputMode);
    }
    

}

void gpio_write_pin(GPIO_Type *gpio , int IO_num , int value){
    if(value == 0){
        gpio->DR &= ~(1<<IO_num);
    }
    else{
        gpio->DR |= (1<<IO_num);
    }
}

int gpio_read_pin(GPIO_Type *gpio , int IO_num){
    return ((gpio->DR>>IO_num) & 0x01);
}

void gpio_interruput_enable(GPIO_Type *gpio , int IO_num ){
    gpio->IMR |= (1<<IO_num);

}

void gpio_interruput_disable(GPIO_Type *gpio , int IO_num ){
    gpio->IMR &= ~(1<<IO_num);

}

void gpio_interruput_clearflags(GPIO_Type *gpio , int IO_num ){
    gpio->ISR |= (1<<IO_num);

}

void gpio_interruput_init(GPIO_Type *gpio , int IO_num , gpio_interrput_mode_t mode){
    
    /*将GPIOx_DEGE_SEL清0*/
    gpio->EDGE_SEL &= ~(1<<IO_num);
    /*设置中断方式*/
    uint32_t *icr;
    int pin = IO_num;
    if(IO_num >= 0 && IO_num <= 15){
        icr = &(gpio->ICR1);
    }
    if(IO_num >= 16 && IO_num <= 31){
        icr = &(gpio->ICR2);
        pin = IO_num-16;
    }
    switch(mode){
        case kGPIO_INTLowLevel:
            *icr &= ~(3 << (2*pin)) ;
            break;
        case kGPIO_INTHighLevel:
            *icr &= ~(3 << (2*pin)) ;
            *icr |= (1 << (2*pin)) ;
            break;
        case kGPIO_INTRisingEdge:
            *icr &= ~(3 << (2*pin)) ;
            *icr |= (2 << (2*pin)) ;
            break;
        case kGPIO_INTFallingEdge:
            *icr &= ~(3 << (2*pin)) ;
            *icr |= (3 << (2*pin)) ;
            break;
        case kGPIO_INTRisingOrFallingEdge:
            gpio->EDGE_SEL |= (1<<IO_num) ;
            break;
        default:
            break;

    }  

}